#include "state_parser.h"

bool StateParser::ParseState(const char* state_file, std::string state_id, std::vector<GameObject*>* objects, std::vector<std::string>* texture_id) {
    tinyxml2::XMLDocument xml_doc;

    // load the state file
    if (xml_doc.LoadFile(state_file) != 0) {  // XML_SUCCESS = 0
        Log(xml_doc.ErrorStr());
        return false;
    }

    // get the root element
    tinyxml2::XMLElement* root = xml_doc.RootElement();  // into STATE lable

    tinyxml2::XMLElement* state_root = nullptr;
    // get this states root node and assign it to state_root
    for (tinyxml2::XMLElement* e = root->FirstChildElement(); e != nullptr; e = e->NextSiblingElement()) {
        if (e->Value() == state_id) {  // MENU (PLAY GAMEOVER)
            state_root = e;
        }
    }

    tinyxml2::XMLElement* texture_root = nullptr;
    // get the root of texture elements
    for (tinyxml2::XMLElement* e = state_root->FirstChildElement(); e!=nullptr; e = e->NextSiblingElement()) {
        if (e->Value() == std::string("TEXTURES")) {  // MENU (PLAY GAMEOVER)'s subelement
            texture_root = e;
        }
    }
    // parse the texture
    ParseTextures(texture_root, texture_id);

    tinyxml2::XMLElement* object_root = nullptr;
    // get the root node of objects
    for (tinyxml2::XMLElement* e = state_root->FirstChildElement(); e != nullptr; e= e->NextSiblingElement()) {
        if (e->Value() == std::string("OBJECTS")) {
            object_root = e;
        }
    }
    // parse OBJECTS
    ParseObjects(object_root, objects);

    return true;
}

void StateParser::ParseTextures(tinyxml2::XMLElement* texture_root, std::vector<std::string>* texture_id) {
    for (tinyxml2::XMLElement* e = texture_root->FirstChildElement(); e != nullptr; e = e->NextSiblingElement() ) {
        std::string filename = e->Attribute("filename");
        std::string id = e->Attribute("id");
        texture_id->push_back(id);
        TheTM::instance().Load(filename, id, TheGame::instance().get_renderer());
    }
}

void StateParser::ParseObjects(tinyxml2::XMLElement* object_root, std::vector<GameObject*>* objects) {
    for (tinyxml2::XMLElement* e = object_root->FirstChildElement(); e != nullptr; e = e->NextSiblingElement()) {
        int x, y, width, height, num_frames, callback_id, anim_speed;
        std::string texture_id;
        x = e->IntAttribute("x");
        y = e->IntAttribute("y");
        width = e->IntAttribute("width");
        height = e->IntAttribute("height");
        num_frames = e->IntAttribute("num_frames");
        callback_id = e->IntAttribute("callback_id");
        anim_speed = e->IntAttribute("anim_speed");
        texture_id = e->Attribute("texture_id");

        GameObject* game_object = TheGOF::instance().Create(e->Attribute("type"));
        game_object->Load(new LoadParams(x, y, width, height, num_frames, texture_id, callback_id, anim_speed));
        objects->push_back(game_object);
    }
}
